using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
//using System.Windows.Forms;

using System.Runtime.InteropServices;
using System.Drawing;
using System.Globalization;

namespace PocketLibrary
{
    public class FileTransferArgs : EventArgs
    {
        public float ProgressPercentage
        {
            get
            {

                float percent = ((float)FileTransferred / (float)FileSize) * 100;

                return percent;
            }
        }

        public string ErrorMessage = "";

        public long FileSize;
        public long FileTransferred;

        public FileTransferArgs(long filesize, long transferred)
        {
            this.FileSize = filesize;
            this.FileTransferred = transferred;
        }
    }

    public class RequestProgressArgs : EventArgs
    {
        int iProgress = 0;
        string sMethod = "Unknown";

        public int Progress
        {
            get
            {
                return iProgress;
            }
        }

        public string ApiMethod
        {
            get { return sMethod; }
        }

        /// <summary>
        /// Api request progress percentage
        /// </summary>
        /// <param name="Progress">progress percentage</param>
        public RequestProgressArgs(int Progress)
        {
            if (Progress > 100)
                iProgress = 100;
            else if (Progress < 0)
                iProgress = 0;
            else
                iProgress = Progress;
        }

        public RequestProgressArgs(string Method)
        {
            sMethod = Method;
        }

        public RequestProgressArgs(int Progress, string Method)
        {
            if (Progress > 100)
                iProgress = 100;
            else if (Progress < 0)
                iProgress = 0;
            else
                iProgress = Progress;
            sMethod = Method;
        }
    }



    public delegate void UploadProgressHandler(object sender, UploadProgressEventArgs e);

    public class UploadProgressEventArgs : EventArgs
    {
        private bool _complete;

        private int _bytes;

        private int _totalbytes;

        /// <summary>
        /// Number of bytes transfered so far.
        /// </summary>
        public int Bytes
        {
            get { return _bytes; }
        }

        /// <summary>
        /// True if all bytes have been uploaded.
        /// </summary>
        public bool Complete
        {
            get { return _complete; }
        }

        /// <summary>
        /// Total number of bytes to transfer
        /// </summary>
        public int TotalBytes
        {
            get { return _totalbytes; }
        }

        /// <summary>
        /// get current progress of file transfer
        /// </summary>
        public int CurrentProgress
        {
            get
            {
                return (int)(((float)this.Bytes / (float)this.TotalBytes) * 100);
            }
        }

        internal UploadProgressEventArgs(int bytes, bool complete)
        {
            _bytes = bytes;
            _complete = complete;
            if (complete)
                _totalbytes = _bytes;
        }

        internal UploadProgressEventArgs(int bytes, int total, bool complete)
        {
            _bytes = bytes;
            _totalbytes = total;
            _complete = complete;
        }

    }

    public delegate void RequestProgressHandler(RequestProgressArgs args);

    public delegate void LoginProgressHandler(EventArgs args);

    public class HelperUtils
    {
        /// <summary>
        /// Turns a byte array to hex string
        /// </summary>
        /// <param name="data">byte array</param>
        /// <returns>Hex string</returns>
        private static string ByteArrayToHexString(byte[] data)
        {
            StringBuilder sb = new StringBuilder(data.Length * 3);
            foreach (byte b in data)
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0'));
            return sb.ToString().ToLower();
        }

        /// <summary>
        /// Creates a md5 hash from string
        /// </summary>
        /// <param name="request">string to hash</param>
        /// <returns>md5 hash string</returns>
        public static string MD5String(string request)
        {
            MD5 mymd5 = MD5.Create();
            byte[] hash = mymd5.ComputeHash(Encoding.ASCII.GetBytes(request));
            return ByteArrayToHexString(hash);
        }

        public static string ResolveMimeType(string fileName)
        {
            switch (Path.GetExtension(fileName))
            {
                case ".txt":
                    return "text/plain";
                case ".html":
                    return "text/html";
                case ".htm":
                    return "text/html";
                case ".jpg":
                    return "image/jpeg";
                case ".png":
                    return "image/png";
                case ".gif":
                    return "image/gif";
                default:
                    return "application/octet-stream";
            }
        }

        /// <summary>
        /// Writes messages to errorlog
        /// </summary>
        /// <param name="message"></param>
        public static void ErrorLog(string message)
        {
            using (FileStream fs = new FileStream(HelperUtils.ApplicationPath + "errorlog.txt", FileMode.Append))
            using (StreamWriter sr = new StreamWriter(fs))
            {
                sr.WriteLine("{0}::{1}", DateTime.Now, message);
            }
        }

        /// <summary>
        /// Gets application path
        /// </summary>
        public static string ApplicationPath
        {
            get
            {
                return System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\";
            }
        }

        // http://blogs.msdn.com/michkap/archive/2007/05/14/2629747.aspx
        //public static string RemoveDiacritics(string stIn)
        //{
        //    string stFormD = stIn.Normalize(NormalizationForm.FormD);
        //    StringBuilder sb = new StringBuilder();

        //    for (int ich = 0; ich < stFormD.Length; ich++)
        //    {
        //        UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
        //        if (uc != UnicodeCategory.NonSpacingMark)
        //        {
        //            sb.Append(stFormD[ich]);
        //        }
        //    }

        //    return (sb.ToString().Normalize(NormalizationForm.FormC));
        //}
    }



    /*
        public class DpiHelper
        {
            /// <summary>
            /// The real dpi of the device.
            /// </summary>
            private static int dpi = SafeNativeMethods.GetDeviceCaps(IntPtr.Zero, 88);

            /// <summary>
            /// Adjust the sizes of controls to account for the DPI of the device.
            /// </summary>
            /// <param name="parent">The parent node of the tree of controls to adjust.</param>
            public static void AdjustAllControls(Control parent)
            {
                if (dpi == 96)
                {
                    return;
                }
                foreach (Control child in parent.Controls)
                {
                    AdjustControl(child);
                    AdjustAllControls(child);
                }
            }



            public static void AdjustControl(Control control)
            {
                control.Bounds = new Rectangle(
                      control.Left * dpi / 96,
                      control.Top * dpi / 96,
                      control.Width * dpi / 96,
                      control.Height * dpi / 96);
            }


            /// <summary>
            /// Scale a coordinate to account for the dpi.
            /// </summary>
            /// <param name="x">The number of pixels at 96dpi.</param>
            /// <returns></returns>
            public static int Scale(int x)
            {
                return x * dpi / 96;
            }


            private class SafeNativeMethods
            {
                [DllImport("coredll.dll")]
                static internal extern int GetDeviceCaps(IntPtr hdc, int nIndex);
            }
        }
    /**/
}
